#include <stdlib.h>
#include <gmp.h>

class Integer {

public:

  Integer();
  Integer(int);
  Integer(char *);
 ~Integer();

  Integer(const Integer &);                  // copy constructor
  Integer & operator  = (const Integer &);   // assignment
  Integer & operator  = (int);               

  Integer & operator += (const Integer &);
  Integer & operator += (int);

  friend Integer operator + (const Integer &, const Integer &);
  Integer operator + (const Integer &);
  Integer operator + (int);

  Integer & operator -= (const Integer &);
  Integer & operator -= (int);

  friend Integer operator - (const Integer &, const Integer &);
  Integer operator - (const Integer &);
  Integer operator - ();

  Integer & operator *= (const Integer &);
  Integer & operator *= (int);

  friend Integer operator * (const Integer &, const Integer &);
  Integer operator * (const Integer &);
  Integer operator * (int);

  Integer & operator /= (const Integer &);
  Integer & operator /= (int);

  Integer operator / (const Integer &);
  Integer operator / (int);

  Integer operator % (const Integer &);

  Integer & operator |= (int);
  Integer operator | (int);

  Integer & operator <<= (int);
  friend Integer operator >> (const Integer &, int);
  friend Integer operator << (const Integer &, int);

  friend int  testbit(const Integer &, long);
  friend void setbit(Integer &, long);

  friend int  operator == (const Integer &, int);
  friend int  operator == (int, const Integer &);
  friend int  operator != (const Integer &, int);
  friend int  operator != (int, const Integer &);
  friend int  operator <= (const Integer &, int);
  friend int  operator >  (const Integer &, int);
  friend int  operator <  (int, const Integer &);
  friend int  operator >= (const Integer &, const Integer &);
  friend int  operator <  (const Integer &, const Integer &);
  friend int  operator >  (const Integer &, const Integer &);
  friend int  operator == (const Integer &, const Integer &);

  friend void divide(const Integer &, const Integer &, Integer &, Integer &);
  friend Integer Ipow(long, long);
  friend long    lg(Integer);
  friend Integer gcd(const Integer &, const Integer &);

  friend void mod(const Integer &, const Integer &, Integer &);
  friend void mul(const Integer &, const Integer &, Integer &);

  friend Integer  sqr(const Integer &);
  friend int     sign(const Integer &);


  char * Value();

private:

  Integer(mpz_t);
  Integer & operator += (mpz_t);
  Integer & operator -= (mpz_t);
  Integer & operator *= (mpz_t);

  mpz_t value;    // We only represent gmp "Integers"

};

